ESM335x外部中斷輸入應(yīng)用
ESM335x嵌入式主板引出了2路外部中斷輸入,IRQ1和IRQ2。中斷上升沿有效,分別與GPIO24和GPIO25復(fù)用管腳。Linux-4.1.6之前采用了異步IO的方式通過(guò)SIGIO通知應(yīng)用程序有中斷發(fā)生,我們?cè)贚inux-4.1.6 IRQ驅(qū)動(dòng)中增加了對(duì)select函數(shù)的支持,select函數(shù)使用戶(hù)在應(yīng)用程序中可以更方便的獲取中斷狀態(tài)。
Linux系統(tǒng)IRQ外部中斷的應(yīng)用
IRQ1和IRQ2對(duì)應(yīng)的設(shè)備文件分別是:/dev/em335x_irq1和/dev/em335x-irq2.應(yīng)用程序使用IRQ外部中斷功能需要先打開(kāi)相應(yīng)的設(shè)備文件:
int irq_no = 1;
sprintf( device, "/dev/em335x_irq%d", irq_no );
irq_fd = open(device, O_RDWR, S_IRUSR | S_IWUSR);
if (irq_fd < 0)
{
printf("can not open /dev/em335x_irq1 device file!\n");
return -1;
}
之后設(shè)置使用異步IO或者使用select函數(shù)獲取中斷狀態(tài),異步IO方式可參考技術(shù)手冊(cè),不再建議用戶(hù)使用。
select函數(shù)
由于外部中斷輸入的時(shí)間是不確定的,需要在循環(huán)中不停的調(diào)用select函數(shù)以檢查設(shè)備文件的讀狀態(tài),所以一般會(huì)創(chuàng)建一個(gè)線(xiàn)程來(lái)調(diào)用select函數(shù),主程序繼續(xù)執(zhí)行其他的操作。線(xiàn)程函數(shù)如下:
int IRQSelectThreadFunc(void* lparam)
{
int fd = * (int*)lparam;
fd_set fdRead;
struct timeval aTime;
int ret,exitflag=1; //exitflag在程序其他線(xiàn)程中改變
while(1)
{
FD_ZERO(&fdRead);
FD_SET(fd,&fdRead);
aTime.tv_sec = 2; //s
aTime.tv_usec = 0; //us
ret = select ( fd+1, &fdRead, NULL, NULL, &aTime );
if ( ret<0 )
printf( "select, something wrong!\n " );
if ( ret>0 )
{
if ( FD_ISSET(fd, &fdRead) )
{
//用戶(hù)可以在此加入中斷發(fā)生后的處理操作
nIrqCounter++;
printf( "there is a IRQ!!!\n" );
}
}
if ( exitflag==0 )
break;
//判斷程序運(yùn)行狀態(tài),跳出循環(huán)
}
pthread_exit( NULL );
return 0;
}
創(chuàng)建線(xiàn)程:
pthread_attr_t attr;
pthread_t m_thread;
int res;
// 創(chuàng)建select線(xiàn)程
res = pthread_attr_init(&attr);
if( res!=0 )
{
printf("Create attribute failed\n" );
}
// 設(shè)置線(xiàn)程綁定屬性
res = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
// 設(shè)置線(xiàn)程分離屬性
res += pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
if( res!=0 )
{
printf( "Setting attribute failed\n" );
}
res = pthread_create( &m_thread, &attr, (void *(*) (void *))&IRQSelectThreadFunc, &irq_fd );
if( res!=0 )
{
return -1;
}
pthread_attr_destroy( &attr );
用戶(hù)在應(yīng)用程序中創(chuàng)建新的線(xiàn)程使用select函數(shù)查詢(xún)中斷設(shè)備文件的狀態(tài),如果有中斷發(fā)生select函數(shù)將會(huì)返回大于0的數(shù)值,用戶(hù)進(jìn)一步判斷是哪一個(gè)設(shè)備文件有中斷發(fā)生,然后執(zhí)行相應(yīng)的中斷處理操作。
異步IO和select函數(shù)的比較
異步IO和select函數(shù)的功能都是相同的,即通知用戶(hù)有中斷發(fā)生,從而執(zhí)行用戶(hù)在應(yīng)用程序中設(shè)置的中斷處理操作;兩者由于在內(nèi)核中使用的事件通知機(jī)制不同,在應(yīng)用程序中的設(shè)置方法差別很大,執(zhí)行的方式也不同(見(jiàn)程序),select函數(shù)采用阻塞的方式獲取讀狀態(tài),不占用CPU資源,可以提高程序運(yùn)行效率。兩者最大的差異在于當(dāng)用戶(hù)需要在一個(gè)應(yīng)用程序中檢查多個(gè)中斷輸入設(shè)備文件的狀態(tài)時(shí)(同時(shí)使用IRQ1和IRQ2),只能使用select函數(shù)才能確定具體是哪個(gè)中斷設(shè)備文件有中斷發(fā)生,使用異步IO不能確定。因此我們建議用戶(hù)在程序中使用select函數(shù)來(lái)管理IRQ外部中斷輸入。
如有疑問(wèn)請(qǐng)隨時(shí)與我們聯(lián)系。
提交
Windows下STM32單片機(jī)eclipse編譯環(huán)境搭建
Android Studio應(yīng)用開(kāi)發(fā)簡(jiǎn)介
WinCE工控主板WiFi解決方案
敬請(qǐng)關(guān)注成都英創(chuàng)微信公眾號(hào)
WinCE工控主板通過(guò)PPI協(xié)議連接西門(mén)子PLC